home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGambit 2.0 / sources1 / Runtime (.c & .h) / emul.c < prev    next >
Encoding:
Text File  |  1992-06-04  |  15.1 KB  |  257 lines  |  [TEXT/KAHL]

  1. 0x3c) *gen_ptr++ = code_ptr[code_len++];
  2. }
  3.  
  4. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  5.  
  6. void long_mul()
  7. { pstate->temp[1] = pstate->temp[1] * pstate->temp[0];
  8. }
  9.  
  10.  
  11. void long_div()
  12. { pstate->temp[1] = pstate->temp[2] % pstate->temp[0];
  13.   pstate->temp[2] = pstate->temp[2] / pstate->temp[0];
  14. }
  15.  
  16.  
  17. long emul_M68020_instr( code_ptr )
  18. short *code_ptr;
  19. { short *p1, *p2, *p3;
  20.   gen_ptr = gen;
  21.   code_len = 2;
  22.   *gen_ptr++ = MOVE_L_PINCA7_A5_DISP_OP;
  23.   *gen_ptr++ = pstate_offset( &pstate->temp[3] );
  24.   switch (code_ptr[0] & 0xffc0)
  25.   { case 0x4c00: /* MULS.L <ea>,Dl */
  26.     { long ea, dl_reg;
  27.       if ((code_ptr[1] & 0x8ff8) != 0x0800) goto error;
  28.       dl_reg = (code_ptr[1] & 0x7000) >> 12;
  29.       ea = code_ptr[0] & 0x3f;
  30.       *gen_ptr++ = MOVE_L_EA_A5_DISP_OP+ea;
  31.       gen_ea( ea, code_ptr );
  32.       *gen_ptr++ = pstate_offset( &pstate->temp[0] );
  33.       *gen_ptr++ = MOVE_L_EA_A5_DISP_OP+dl_reg;
  34.       *gen_ptr++ = pstate_offset( &pstate->temp[1] );
  35.       *gen_ptr++ = MOVE_L_IMM_PDECA7_OP;
  36.       *(void (**)())gen_ptr = long_mul;  gen_ptr += 2;
  37.       *gen_ptr++ = JSRA6_DISP_OP;
  38.       *gen_ptr++ = table_offset( &sstate->traps[C_TRAP_trap].jmp );
  39.       *gen_ptr++ = MOVE_L_A5_DISP_EA_OP+(dl_reg<<9);
  40.       *gen_ptr++ = pstate_offset( &pstate->temp[1] );
  41.       break;
  42.     }
  43.     case 0x4c40: /* DIVS.L <ea>,Dr:Dq */
  44.     { long ea, dr_reg, dq_reg;
  45.       if ((code_ptr[1] & 0x8ff8) != 0x0800) goto error;
  46.       dr_reg = code_ptr[1] & 0x7;
  47.       dq_reg = (code_ptr[1] & 0x7000) >> 12;
  48.       ea = code_ptr[0] & 0x3f;
  49.       *gen_ptr++ = MOVE_L_EA_A5_DISP_OP+ea;
  50.       gen_ea( ea, code_ptr );
  51.       *gen_ptr++ = pstate_offset( &pstate->temp[0] );
  52.       *gen_ptr++ = MOVE_L_EA_A5_DISP_OP+dr_reg;
  53.       *gen_ptr++ = pstate_offset( &pstate->temp[1] );
  54.       *gen_ptr++ = MOVE_L_EA_A5_DISP_OP+dq_reg;
  55.       *gen_ptr++ = pstate_offset( &pstate->temp[2] );
  56.       *gen_ptr++ = MOVE_L_IMM_PDECA7_OP;
  57.       *(void (**)())gen_ptr = long_div;  gen_ptr += 2;
  58.       *gen_ptr++ = JSRA6_DISP_OP;
  59.       *gen_ptr++ = table_offset( &sstate->traps[C_TRAP_trap].jmp );
  60.       *gen_ptr++ = MOVE_L_A5_DISP_EA_OP+(dr_reg<<9);
  61.       *gen_ptr++ = pstate_offset( &pstate->temp[1] );
  62.       *gen_ptr++ = MOVE_L_A5_DISP_EA_OP+(dq_reg<<9);
  63.       *gen_ptr++ = pstate_offset( &pstate->temp[2] );
  64.       break;
  65.     }
  66.     default:
  67.       goto error;
  68.   }
  69.   *gen_ptr++ = MOVE_L_A5_DISP_PDECA7_OP;
  70.   *gen_ptr++ = pstate_offset( &pstate->temp[3] );
  71.   *gen_ptr++ = RTS_OP;
  72.   p1 = (short *)pstate->emul_code_bot;
  73.   while (p1 < (short *)emul_code_alloc)
  74.   { p2 = p1;
  75.     p3 = gen;
  76.     while ((p3 < gen_ptr) && (*p2 == *p3)) { p2++; p3++; }
  77.     if (p3 == gen_ptr)
  78.     { *code_ptr++ = JSRA5_DISP_OP;
  79.       *code_ptr++ = pstate_offset( p1 );
  80.       while (code_len > 2) { *code_ptr++ = NOP_OP; code_len--; }
  81.       return 0;
  82.     }
  83.     p1++;
  84.   }
  85.   if (emul_code_alloc+(gen_ptr-gen)*sizeof(short) > emul_code_top)
  86.   { os_err = "Emulation code memory overflow"; return 1; }
  87.   *code_ptr++ = JSRA5_DISP_OP;
  88.   *code_ptr++ = pstate_offset( emul_code_alloc );
  89.   while (code_len > 2) { *code_ptr++ = NOP_OP; code_len--; }
  90.   p1 = gen;
  91.   while (p1 < gen_ptr)
  92.   { *(short *)emul_code_alloc = *p1++;
  93.     emul_code_alloc += sizeof(short);
  94.   }
  95.   return 0;
  96.   error:
  97.   os_err = "Unknown M68020 instruction";
  98.   return 1;
  99. }
  100.  
  101. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  102.  
  103. #ifdef NO_EMUL_M68881
  104.  
  105. long emul_M68881_instr( code_ptr )
  106. short *code_ptr;
  107. { os_err = "No M68881 emulation";
  108.   return 1;
  109. }
  110.  
  111. #else
  112.  
  113. #include <math.h>
  114.  
  115. int matherr( x )
  116. struct exception *x;
  117. { return 1; /* don't trap on error */
  118. }
  119.  
  120. void fp_mov_l_to_fp0()   { pstate->fp0 = pstate->temp[0]; }
  121. void fp_mov_l_from_fp0() { pstate->temp[0] = pstate->fp0; }
  122.  
  123. void fp_mov_d_to_fp0()   { pstate->fp0 = *pstate->fp_ptr; }
  124. void fp_mov_d_from_fp0() { *pstate->fp_ptr = pstate->fp0; }
  125.  
  126. void fp_abs_to_fp0()     { pstate->fp0 = fabs( (double)*pstate->fp_ptr ); }
  127. void fp_abs_from_fp0()   { *pstate->fp_ptr = fabs( (double)pstate->fp0 ); }
  128.  
  129. void fp_int_to_fp0()
  130. { double x = *pstate->fp_ptr;
  131.   double y = fmod( x, 2.0 );
  132.   if (y == 0.5)
  133.     pstate->fp0 = x-0.5;
  134.   else if (y == -1.5)
  135.     pstate->fp0 = x-0.5;
  136.   else 
  137.     pstate->fp0 = floor( 0.5+x );
  138. }
  139.  
  140. void fp_int_from_fp0()
  141. { double x = pstate->fp0;
  142.   double y = fmod( x, 2.0 );
  143.   if (y == 0.5)
  144.     *pstate->fp_ptr = x-0.5;
  145.   else if (y == -1.5)
  146.     *pstate->fp_ptr = x-0.5;
  147.   else 
  148.     *pstate->fp_ptr = floor( 0.5+x );
  149. }
  150.  
  151. void fp_intrz_to_fp0()
  152. { if (*pstate->fp_ptr < 0.0)
  153.     pstate->fp0 = -floor( -(double)*pstate->fp_ptr );
  154.   else
  155.     pstate->fp0 = floor( (double)*pstate->fp_ptr );
  156. }
  157.  
  158. void fp_intrz_from_fp0()
  159. { if (pstate->fp0 < 0.0)
  160.     *pstate->fp_ptr = -floor( -(double)pstate->fp0 );
  161.   else
  162.     *pstate->fp_ptr = floor( (double)pstate->fp0 );
  163. }
  164.  
  165. void fp_sqrt_to_fp0()    { pstate->fp0 = sqrt( (double)*pstate->fp_ptr ); }
  166. void fp_sqrt_from_fp0()  { *pstate->fp_ptr = sqrt( (double)pstate->fp0 ); }
  167.  
  168. void fp_etox_to_fp0()    { pstate->fp0 = exp( (double)*pstate->fp_ptr ); }
  169. void fp_etox_from_fp0()  { *pstate->fp_ptr = exp( (double)pstate->fp0 ); }
  170.  
  171. void fp_logn_to_fp0()    { pstate->fp0 = log( (double)*pstate->fp_ptr ); }
  172. void fp_logn_from_fp0()  { *pstate->fp_ptr = log( (double)pstate->fp0 ); }
  173.  
  174. void fp_sin_to_fp0()     { pstate->fp0 = sin( (double)*pstate->fp_ptr ); }
  175. void fp_sin_from_fp0()   { *pstate->fp_ptr = sin( (double)pstate->fp0 ); }
  176.  
  177. void fp_cos_to_fp0()     { pstate->fp0 = cos( (double)*pstate->fp_ptr ); }
  178. void fp_cos_from_fp0()   { *pstate->fp_ptr = cos( (double)pstate->fp0 ); }
  179.  
  180. void fp_tan_to_fp0()     { pstate->fp0 = tan( (double)*pstate->fp_ptr ); }
  181. void fp_tan_from_fp0()   { *pstate->fp_ptr = tan( (double)pstate->fp0 ); }
  182.  
  183. void fp_asin_to_fp0()    { pstate->fp0 = asin( (double)*pstate->fp_ptr ); }
  184. void fp_asin_from_fp0()  { *pstate->fp_ptr = asin( (double)pstate->fp0 ); }
  185.  
  186. void fp_acos_to_fp0()    { pstate->fp0 = acos( (double)*pstate->fp_ptr ); }
  187. void fp_acos_from_fp0()  { *pstate->fp_ptr = acos( (double)pstate->fp0 ); }
  188.  
  189. void fp_atan_to_fp0()    { pstate->fp0 = atan( (double)*pstate->fp_ptr ); }
  190. void fp_atan_from_fp0()  { *pstate->fp_ptr = atan( (double)pstate->fp0 ); }
  191.  
  192. void fp_add_to_fp0()     { pstate->fp0 = pstate->fp0 + *pstate->fp_ptr; }
  193. void fp_add_from_fp0()   { *pstate->fp_ptr = *pstate->fp_ptr + pstate->fp0; }
  194.  
  195. void fp_sub_to_fp0()     { pstate->fp0 = pstate->fp0 - *pstate->fp_ptr; }
  196. void fp_sub_from_fp0()   { *pstate->fp_ptr = *pstate->fp_ptr - pstate->fp0; }
  197.  
  198. void fp_mul_to_fp0()     { pstate->fp0 = pstate->fp0 * *pstate->fp_ptr; }
  199. void fp_mul_from_fp0()   { *pstate->fp_ptr = *pstate->fp_ptr * pstate->fp0; }
  200.  
  201. void fp_div_to_fp0()     { pstate->fp0 = pstate->fp0 / *pstate->fp_ptr; }
  202. void fp_div_from_fp0()   { *pstate->fp_ptr = *pstate->fp_ptr / pstate->fp0; }
  203.  
  204. void fp_cmp_to_fp0()     { pstate->fp_cmp1 = *pstate->fp_ptr; pstate->fp_cmp2 = pstate->fp0; }
  205. void fp_cmp_from_fp0()   { pstate->fp_cmp1 = pstate->fp0; pstate->fp_cmp2 = *pstate->fp_ptr; }
  206.  
  207.  
  208. void fp_beq()
  209. { if (pstate->fp_cmp2 == pstate->fp_cmp1) pstate->temp[3] += pstate->temp[0];
  210. }
  211.  
  212.  
  213. void fp_bne()
  214. { if (pstate->fp_cmp2 != pstate->fp_cmp1) pstate->temp[3] += pstate->temp[0];
  215. }
  216.  
  217.  
  218. void fp_blt()
  219. { if (pstate->fp_cmp2 < pstate->fp_cmp1) pstate->temp[3] += pstate->temp[0];
  220. }
  221.  
  222.  
  223. void fp_bgt()
  224. { if (pstate->fp_cmp2 > pstate->fp_cmp1) pstate->temp[3] += pstate->temp[0];
  225. }
  226.  
  227.  
  228. void fp_ble()
  229. { if (pstate->fp_cmp2 <= pstate->fp_cmp1) pstate->temp[3] += pstate->temp[0];
  230. }
  231.  
  232.  
  233. void fp_bge()
  234. { if (pstate->fp_cmp2 >= pstate->fp_cmp1) pstate->temp[3] += pstate->temp[0];
  235. }
  236.  
  237.  
  238. long emul_M68881_instr( code_ptr )
  239. short *code_ptr;
  240. { short *p1, *p2, *p3;
  241.   gen_ptr = gen;
  242.   code_len = 2;
  243.   *gen_ptr++ = MOVE_L_PINCA7_A5_DISP_OP;
  244.   *gen_ptr++ = pstate_offset( &pstate->temp[3] );
  245.   switch (code_ptr[0] & 0xffc0)
  246.   { case 0xf200: /* floating point operation */
  247.     { long ea, f_reg, op;
  248.       ea = code_ptr[0] & 0x003f;
  249.       op = code_ptr[1] & 0x003f;
  250.       f_reg = (code_ptr[1] & 0x0380) >> 7;
  251.       if (f_reg != 0) goto error;
  252.       if (op == 0) /* fmov ? */
  253.         switch (code_ptr[1] & 0xfc00)
  254.         { case 0x4000: /* fmov.l <ea>,fp0 */
  255.             *gen_ptr++ = MOVE_L_EA_A5_DISP_OP+ea;
  256.             gen_ea( ea, code_ptr );
  257.             *gen_ptr++ = pstate_offset(